# For audio recording and messaging
import time
import random

import os, datetime
from util.persist import *

SENT_FILE = "_sent_am.data"
RECV_FILE = "_recv_am.data"

import gobject

class AudioManager(gobject.GObject):
    """ 
        Manages audio messages
    """
    
    __gsignals__ = {

            'sent_audio' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
                    (gobject.TYPE_INT, gobject.TYPE_INT,)),
            'received_audio' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,
                    (gobject.TYPE_PYOBJECT,)),
    }
    
    def __init__(self, am, mixer, db):
        # stores audio messages indexed by guid
        gobject.GObject.__init__( self ) 
        self.am = am
        self.mixer = mixer
        #self.__createMessagingPipelines()
        self.path = ahcon.MESSAGING_PATH+'apps/audio/'
        if not os.path.exists(self.path):
            print "Creating path for audio"
            os.makedirs(self.path)
                            
        self.temp_rec_file_name = self.path+"temp_audio.wav"
        self._type = uicon.AUDIOMSG
        self.__db = db

    
    def sendAudio(self, senddata):
        """
            Called when the UI sends a request to send a message
            @param senddata: dictionary with fields
                1. 'id': temporary id
                2. 'tags': tags of information
                3. 'priority': priority of data
                4. 'recipients': the recipients of data
                5. 'strength': the strength of spread
                6. 'reply': the guid of the message this message is replying to
            @return the official guid to the UI of the sent message, -1 if it failed sending
        """

        tags = senddata['tags']
        id = senddata['id']
        recipients = senddata['recipients']

        # metadata to send with audio
        meta = {}
        meta[ahcon.PRIORITY_KEY] = senddata['priority']
        meta[ahcon.EXPIRES_KEY] = time.time()+3000    #  datetime.datetime.now() + datetime.timedelta(days=1)
        meta[ahcon.STRENGTH_KEY] = senddata['strength']

        try:
            reply = senddata['reply']
            meta[ahcon.REPLY_KEY] = reply
        except KeyError:
            print "Not a reply audio message"
        
        # Right now, let's rename to the current time
        newid = random.randint(1,100000)
        newpath = self.path + "a_" + str(newid) + ".audio"
        if not os.path.exists(self.temp_rec_file_name):
            print "Requested audio file to send didn't exist"
            self.emit('sent_audio', -1, uicon.AUDIOMSG)
            return
        length = common.GetAudioDuration(self.temp_rec_file_name)
        meta[ahcon.LENGTH_KEY] = length
        #newid = time.time()
        #os.chdir(self.path)
        #print os.getcwd()
        #oldpath = str(id) + ".audio"
        #newpath = str(newid) + ".audio"
        
        print "Renaming from",self.temp_rec_file_name,"to",newpath
        os.rename(self.temp_rec_file_name, newpath)
        
        guid, src = self.am.sendMessage(uicon.AUDIOMSG, recipients, newpath, tags, meta)
        
        msg = {'guid':guid, 'type':self._type, 'src':src, 'destinations':recipients, 'tags':tags, 'url':newpath,'meta':meta, 'created':time.time()}
        self.__db.putSentMsgMeta(msg)
        print "Sent audio message: guid:",guid,"sub:",tags,"recip:",recipients
        #persist(self.sent_msgs, self.path+SENT_FILE)
        
        self.emit('sent_audio', guid, uicon.AUDIOMSG)
        
    def onMessageReceived(self, guid, src, recipients, tags, url, meta):
        """
            Callback from AsyncManager when audio message is received over the network.
            
            @param guid: the guid of message received
            @type guid: number
            @param src: The guid of the message sender
            @type src: number
            @param recipients: The target recipients of this message
            @type recipients: List[number]
            @param tags: String of comma seperated tags
            @type tags: String
            @param url: The url to the received message
            @type url: String
            @param meta: Metadata attached to this message
            @type meta: dictionary
        """
        print "Received message: ",guid,src,recipients,meta
        print "url: ",url
        
        meta[ahcon.RECV_TIME_KEY] = time.time()

        
        msg = {'guid':guid, 'type':self._type, 'src':src, 'destinations':recipients, 'tags':tags, 'url':url,'meta':meta, 'created':meta[ahcon.CREATED_KEY]}
        self.__db.putRcvdMsgMeta(msg)
        name = "Voice message from " + str(src) + " tag: " + str(tags)
        # url is needed for mixer to play back audio
        self.emit('received_audio', { 'subcommand': uicon.ADD, 
                                     'id':guid, 
                                     'type':self._type, 
                                     'url':url,
                                     'label':tags, 
                                     'status': uicon.EXPIRES_SOON,
                                     'priority': meta.get(ahcon.PRIORITY_KEY, uicon.PRIORITY_LOW),
                                     'date': meta[ahcon.CREATED_KEY]
                                     })
    
    def getAudioDetails(self, guid):
        """
            Called from L{ObjectBroker} when user requests OPEN_OBJECT by double clicking on audio message
        """
        
        #detail = self.recv_msgs[guid]
        #detail['type'] = self._type
        detail = self.__db.getMsgMeta(guid)
        return detail

    def getAllAudio(self):
        """
            Used during initialization to return all items user has
            @return details for every received audio messages
        """
        audio_list = []
        for msg in self.__db.getAllOfType(self._type):
            detail = {'subcommand':uicon.ADD, 'id': msg['id'], 'type': self._type, 'label': msg['tags'], 
                               'url': msg['url'], 'status': -1, 
                               'priority': msg['meta'][ahcon.PRIORITY_KEY],
                               'date' : msg['meta'][ahcon.RECV_TIME_KEY] }
            audio_list.append( detail )
            self.mixer.onAddInput( self, detail )

        return audio_list
        
gobject.type_register( AudioManager )